package com.agentai.framework.common.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Base64;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

/**
 * 二维码生成工具类
 *
 * @author yuwei
 * @date 2024-11-11 11:11
 */
public class QRCodeGenerator {
    /**
     * 生成二维码并转换为 Base64
     *
     * @param content 内容
     * @param width   宽度
     * @param height  高度
     * @return
     * @throws Exception
     */
    public static String generateQRCodeBase64(String content, int width, int height) {
        // 设置二维码参数
        Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 设置容错率
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置字符编码
        ByteArrayOutputStream byteArrayOutputStream = null;

        try {
            // 创建二维码
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            // 转换为BufferedImage
            BufferedImage image = toBufferedImage(bitMatrix);

            // 将BufferedImage转换为Base64
            byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(image, "PNG", byteArrayOutputStream);
        } catch (WriterException | IOException e) {
            throw new RuntimeException(e);
        }
        byte[] imageBytes = byteArrayOutputStream.toByteArray();
        return Base64.getEncoder().encodeToString(imageBytes);
    }


    /**
     * 生成二维码并转换为字节码
     *
     * @param content 内容
     * @param width   宽度
     * @param height  高度
     * @return 二维码的字节数组
     */
    public static byte[] generateQRCodeBytes(String content, int width, int height) {
        // 设置二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 设置容错率
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置字符编码

        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            // 创建二维码
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            // 转换为BufferedImage
            BufferedImage image = toBufferedImage(bitMatrix);

            // 将BufferedImage转换为字节数组
            ImageIO.write(image, "PNG", byteArrayOutputStream);

            return byteArrayOutputStream.toByteArray();
        } catch (WriterException | IOException e) {
            throw new RuntimeException("二维码生成失败", e);
        }
    }


    /**
     * 生成带有Logo的二维码并转换为字节码
     *
     * @param content  内容
     * @param width    宽度
     * @param height   高度
     * @param imageUrl Logo 图片的在线URL
     * @return 二维码的字节数组
     * @throws IOException
     */
    public static byte[] generateQRCodeWithLogoBytes(String content, int width, int height, String imageUrl) throws IOException {
        // 设置二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 设置容错率
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置字符编码

        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            // 创建二维码
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            // 将二维码转换为BufferedImage
            BufferedImage qrImage = toBufferedImage(bitMatrix);

            // 1. 图片的在线URL
            URL url = new URL(imageUrl);
            // 通过URL打开一个输入流
            InputStream inputStream = url.openStream();
            // 读取图片
            BufferedImage logoImage = ImageIO.read(inputStream);

            // 2. 本地图片路径
//            BufferedImage logoImage = ImageIO.read(new File(logoPath));

            // 在二维码中心添加Logo
            int qrWidth = qrImage.getWidth();
            int qrHeight = qrImage.getHeight();
            int logoWidth = logoImage.getWidth();
            int logoHeight = logoImage.getHeight();

            // 计算 Logo 的大小
            int newLogoWidth = qrWidth / 5;  // Logo 的宽度设置为二维码宽度的五分之一
            int newLogoHeight = (logoHeight * newLogoWidth) / logoWidth;  // 保持Logo的比例

            // 计算 Logo 放置的位置
            int x = (qrWidth - newLogoWidth) / 2;
            int y = (qrHeight - newLogoHeight) / 2;

            // 创建一个图形上下文，用于在二维码上绘制Logo
            Graphics2D graphics = qrImage.createGraphics();

            // 绘制二维码
            graphics.drawImage(qrImage, 0, 0, null);
            // 绘制Logo
            graphics.drawImage(logoImage, x, y, newLogoWidth, newLogoHeight, null);
            graphics.dispose();  // 释放资源

            // 将BufferedImage转换为字节数组
            ImageIO.write(qrImage, "PNG", byteArrayOutputStream);

            return byteArrayOutputStream.toByteArray();
        } catch (WriterException e) {
            throw new RuntimeException("二维码生成失败", e);
        }
    }

    /**
     * 生成二维码图片
     *
     * @param content  内容
     * @param width    宽度
     * @param height   高度
     * @param filePath 图片路径+图片名称
     * @throws IOException
     * @throws WriterException
     */
    public static void generateQRCodeImage(String content, int width, int height, String filePath)
            throws IOException, WriterException {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        hints.put(EncodeHintType.MARGIN, 2);

        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }


    // 将BitMatrix转换为BufferedImage
    private static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        image.createGraphics();

        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                image.setRGB(j, i, matrix.get(j, i) ? 0x000000 : 0xFFFFFF); // 黑色和白色
            }
        }
        return image;
    }

/*    public static void main(String[] args) throws IOException, WriterException {

        // 要生成二维码的内容
        String content = "https://www.baidu.com";

        // 生成二维码的Base64编码
        String qrCodeBase64 = generateQRCodeBase64(content, 300, 300);

        System.out.println(qrCodeBase64);

//        generateQRCodeImage("www.baidu.com", 200, 200, "C:\\Users\\pc\\Desktop\\test.png");
    }*/
}
